package com.woniu.adapter;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.sun.org.apache.regexp.internal.RE;
import com.woniu.client.ManagementClient;
import com.woniu.client.ProjectClient;
import com.woniu.inlet.vo.CustomerVo;
import com.woniu.outlet.dao.*;
import com.woniu.outlet.po.*;
import com.woniu.outlet.rabbitmq.MessageRepo;
import com.woniu.outlet.redis.RedisOrderRepo;
import com.woniu.util.MessageStatus;
import com.woniu.util.SnowflakeIdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class OrderAdapter {
    @Autowired
    private OrderPoMapper orderPoMapper;
    @Autowired
    private RedisOrderRepo redisOrderRepo;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private MessageRepo messageRepo;
    @Autowired
    private OrderDetailsMapper orderDetailsMapper;
    @Autowired
    private OrderDeliverMapper orderDeliverMapper;
    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    @Qualifier("orderPtoject")
    private ProjectClient projectClient;

    @Autowired
    @Qualifier("orderManagement")
    private ManagementClient managementClient;

    @Autowired
    private OrderProductionMapper orderProductionMapper;


    //查询所有订单
    public List<OrderPo> findOrders() throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String str = redisOrderRepo.findOrders("order:list");
        List<OrderPo> lists = new ArrayList<>();
        if(!StringUtils.isEmpty(str)){
            CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, OrderPo.class);
            lists = mapper.readValue(str,type);
            return lists;
        }
        lists = orderPoMapper.selectByExample(null);
        //存储到redis中
        redisOrderRepo.saveOrder("order:list",mapper.writeValueAsString(lists));

        //系统日志插入
        managementClient.addSystemLog("查询所有订单");
        return lists;

    }

    //查询订单编号下的所有商品
    public List<OrderPo> findOrderByOrderNo(String orderNo) throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String str = redisOrderRepo.findOrderByOrderNo("order_detail"+orderNo);
        List<OrderPo> lists = new ArrayList<>();
        if(!StringUtils.isEmpty(str)){
            CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, OrderPo.class);
            lists = mapper.readValue(str,type);
            return lists;
        }
        lists = orderPoMapper.selectOrderDetailByOrderNo(orderNo);
        //存储到redis中
        redisOrderRepo.saveOrder("order_detail"+orderNo,mapper.writeValueAsString(lists));

        //系统日志插入
        managementClient.addSystemLog("查询订单");
        return lists;
    }

    //查询订单id下的所有商品
    public List<OrderPo> findOrderById(Long id) throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String str = redisOrderRepo.findOrderByOrderNo("order_detail"+id);
        List<OrderPo> lists = new ArrayList<>();
        if(!StringUtils.isEmpty(str)){
            CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, OrderPo.class);
            lists = mapper.readValue(str,type);
            return lists;
        }
        lists = orderPoMapper.selectOrderDetailById(id);
        //存储到redis中
        redisOrderRepo.saveOrder("order_detail"+id,mapper.writeValueAsString(lists));

        //系统日志插入
        managementClient.addSystemLog("查询订单");
        return lists;
    }

    //添加订单
    public Boolean addOrder(OrderPo orderPo) {
        String orderCreater = orderPo.getOrderCreater();
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        while(!Boolean.TRUE.equals(ops.setIfAbsent("order:"+orderCreater,"s",3000, TimeUnit.MILLISECONDS))){
            return false;
        }
        RLock rLock = redissonClient.getLock("orderlock:"+orderCreater);
        try {
            rLock.lock();
            Thread.sleep(5000);
            //调用系统微服务,查询客户是否存在,不存在则返回,下单失败
            CustomerVo customerVo = managementClient.getCustomerById(orderPo.getCustomerId()).getData();
            if (customerVo == null) {
                return false;
            }
            orderPo.setCreateDate(new Date());
            orderPo.setModifyDate(null);
            orderPo.setEndDate(null);
            orderPo.setExpiryDate(null);
            orderPo.setOverdueStatus("否");
            orderPo.setOrderStatus("待计划");
            SnowflakeIdGenerator snowId = new SnowflakeIdGenerator();
            orderPo.setOrderNo("OD-" + snowId.nextId());
            orderPoMapper.insert(orderPo);
            redisOrderRepo.deleteOrder("order:list");
            //系统日志插入
            managementClient.addSystemLog("添加订单");

        }catch (Exception ex) {
            ex.printStackTrace();
            return false;
        } finally {
            rLock.unlock();
        }
        return true;
    }

    //添加订单明细--判断库存,够则直接减,不够则生产
    public Boolean addOrderDetails(OrderDetails orderDetails) {
        //获取产品id
        Long projectId = orderDetails.getProductId();
        //获取订单编号
        String orderNo = orderDetails.getOrderNo();
        int id = orderDetails.getProductId().intValue();
        String code = projectClient.getProjectCodeById(id).getBody();

        //如果产品code为空或null,则说明该产品不存在
        if(code.equals("没有该产品") || code == null){
            return false;
        }
        //获取产品下单数量
        int num = orderDetails.getNum().intValue();
        //获取仓库减掉的库存数量
//        ResponseEntity<Integer> projectNum = projectClient.projectOut(code, num);
//        //仓库返回的核减数量
//        int integerNum = projectNum.getBody();
        int integerNum = projectClient.projectOut(code, num).getBody();
        //如果库存返回数量等于订单数量，则库存满足订单数量，直接备货
        if (integerNum == num){
            //库存直接减掉,修改订单为待发货状态
//            orderPoMapper.updateStatusByOrderNo(orderNo,"待发货");
            log.info("库存充足,可发货");
        }
        if(integerNum < num){
            //库存不足,库存减掉已有,剩余则需添加至生产计划
            long needNum = num - integerNum;

            OrderProduction orderProduction = new OrderProduction();
            orderProduction.setOrderNo(orderNo);
            orderProduction.setNum(needNum);
            orderProduction.setProjectId(projectId);
            //向订单生产计划表添加数据
            orderProductionMapper.insert(orderProduction);
        }

        orderDetails.setSpare1("未完成");
        orderDetailsMapper.insert(orderDetails);
        redisOrderRepo.deleteOrder("order_detail:list");
        //系统日志插入
        managementClient.addSystemLog("添加订单明细");
        return true;
    }

    //修改订单
    public Boolean updateOrder(OrderPo orderPo) {
        OrderPo orderPo1 = orderPoMapper.selectByPrimaryKey(orderPo.getId());
        if (orderPo1 == null) {
            return false;
        }
        orderPoMapper.updateByPrimaryKeySelective(orderPo);
        redisOrderRepo.deleteOrder("order:list");

        //系统日志插入
        managementClient.addSystemLog("修改订单");
        return true;
    }

    //删除订单(根据订单编号)
    public Boolean deleteOrderByOrderNo(String orderNo) {
        if (orderNo == null){
            return false;
        }
        OrderPo orderPo1 = orderPoMapper.selectOrderPoByOrderNo(orderNo);
        if (orderPo1 == null) {
            return false;
        }
        orderPoMapper.deleteByOrderNo(orderNo);
        orderDetailsMapper.deleteByOrderNo(orderNo);
        redisOrderRepo.deleteOrder("order:list");
        redisOrderRepo.deleteOrder("order_detail"+orderNo);

        //系统日志插入
        managementClient.addSystemLog("删除订单");
        return true;
    }

    //查询所有送货信息
    public List<OrderDeliver> findOrderDeliver() throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String str = redisOrderRepo.findOrderDelivers("order_deliver:list");
        List<OrderDeliver> lists = new ArrayList<>();
        if (!StringUtils.isEmpty(str)){
            CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class,OrderDeliver.class);
            lists = mapper.readValue(str,type);
            return lists;
        }
        lists = orderDeliverMapper.selectByExample(null);
        //存储到redis中
        redisOrderRepo.saveOrder("order_deliver:list",mapper.writeValueAsString(lists));

        //系统日志插入
        managementClient.addSystemLog("查询送货");
        return lists;
    }

    //查询送货信息(根据订单编号)
    public OrderDeliver findOrderDeliverByOrderNo(String orderNo) throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String str = redisOrderRepo.findOrderDeliver("order_deliver"+orderNo);
        OrderDeliver orderDeliver = null;
        if(!StringUtils.isEmpty(str)){
            orderDeliver = mapper.readValue(str, new TypeReference<OrderDeliver>() {
            });
            return orderDeliver;
        }
        orderDeliver = orderDeliverMapper.selectOrderDeliverByOrderNo(orderNo);
        //存储到redis中
        redisOrderRepo.saveOrderDeliver("order_deliver"+orderNo,mapper.writeValueAsString(orderDeliver));
        return orderDeliver;
    }

    //添加送货信息,发邮件给客户邮箱
    public Boolean addOrderDeliver(OrderDeliver orderDeliver) {
        //分布式锁
        String orderNo = orderDeliver.getOrderNo();
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        while(!Boolean.TRUE.equals(ops.setIfAbsent("orderDeliver:"+orderNo,"s",3000, TimeUnit.MILLISECONDS))){
            return false;
        }
        RLock rLock = redissonClient.getLock("orderDeliverlock:"+orderNo);
        try {
            rLock.lock();
            Thread.sleep(5000);
            OrderDeliver orderDeliver1 = orderDeliverMapper.selectByOrderNo(orderDeliver.getOrderNo());
            if (orderDeliver1 != null) {
                return false;
            }
            OrderPo orderPo = new OrderPo();
            orderPo.setOrderStatus("已发货");
            orderPo.setOrderNo(orderDeliver.getOrderNo());
            orderPoMapper.updateStatus(orderPo);
            SnowflakeIdGenerator snowId = new SnowflakeIdGenerator();
            orderDeliver.setId(snowId.nextId());
            orderDeliver.setDeliveryDate(new Date());
            orderDeliverMapper.insert(orderDeliver);
            redisOrderRepo.deleteOrder("order_deliver:list");
            redisOrderRepo.deleteOrder("order_deliver"+orderNo);
            //修改订单状态
            orderPoMapper.updateStatusByOrderNo(orderNo,"已发货");
            //保存要发送的消息内容
            Message message = new Message();
            //未发送
            message.setStatus(MessageStatus.UNSEND.getStatus());
            //消息内容为用户的邮箱信息
            String email = orderDeliver.getEmail();
            message.setMessageContent(email);
            message.setExchange("orderMessage_exchange");
            message.setRoutingKey("orderMessage.add");
            //重试次数默认是10次
            message.setRetryCount(10);
            message.setVersion(1L);
            messageMapper.insertSelective(message);

            //系统日志插入
            managementClient.addSystemLog("新增送货");

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally {
            rLock.unlock();
        }
        return true;
    }

    //修改送货信息
    public Boolean updateOrderDeliver(OrderDeliver orderDeliver) {
        //如果id为null
        if (orderDeliver.getId() == null){
            return false;
        }
        OrderDeliver orderDeliver1 = orderDeliverMapper.selectByPrimaryKey(orderDeliver.getId());
        //如果送货表没有这个id
        if (orderDeliver1 == null){
            return false;
        }
        orderDeliverMapper.updateByPrimaryKeySelective(orderDeliver);
        redisOrderRepo.deleteOrder("order_deliver:list");
        redisOrderRepo.deleteOrder("order_deliver"+orderDeliver.getOrderNo());

        //系统日志插入
        managementClient.addSystemLog("修改送货");
        return true;
    }

    //删除送货信息(根据订单编号)
    public Boolean deleteOrderDeliverByOrderNo(String orderNo) {
        if (orderNo == null){
            return false;
        }
        OrderDeliver orderDeliver = orderDeliverMapper.selectByOrderNo(orderNo);
        if (orderDeliver == null){
            return false;
        }
        orderDeliverMapper.deleteOrderDeliverByOrderNo(orderNo);
        redisOrderRepo.deleteOrder("order_deliver:list");
        redisOrderRepo.deleteOrder("order_deliver"+orderNo);

        //系统日志插入
        managementClient.addSystemLog("删除送货");
        return true;
    }

    //根据订单编号查询id
    public Long findIdByOrderNo(String orderNo) {
        Long id = orderPoMapper.selectIdByOrderNo(orderNo);
        //系统日志插入
        managementClient.addSystemLog("查询订单id");
        return id;
    }

    //查询订单生产计划,并发送邮箱
    public List<OrderProduction> findOrderProductionByOrderNo(String orderNo) {
        List<OrderProduction> lists = orderProductionMapper.selectOrderProductionByOrderNo(orderNo);
        if (lists.size()==0) {
            orderPoMapper.updateStatusByOrderNo(orderNo,"待发货");
            return null;
        }else{
            //保存要发送的消息内容
            Message message = new Message();
            //未发送
            message.setStatus(MessageStatus.UNSEND.getStatus());
            //消息内容为用户的邮箱信息
            message.setMessageContent(lists.toString());
            message.setExchange("orderProduction_exchange");
            message.setRoutingKey("orderProduction.add");
            //重试次数默认是10次
            message.setRetryCount(10);
            message.setVersion(1L);
            messageMapper.insertSelective(message);

            return lists;
        }

    }
}
